#include "mat_ui_animator.h"
#include "mat_sfx_manager.h"

#include "ui/ui_widget.h"


MATUIAnimator&     MATUIAnimator::Instance()
{
	static MATUIAnimator	Inst;
	return Inst;
}

void				MATUIAnimator::Tick(float dt)
{
	for(int i = 0; i < (int)m_AnimatedList.size(); i++)
	{
		m_AnimatedList[i]->Tick(dt);
	}
}
	

MATAnimatedUI*		MATUIAnimator::Add(ui::UIWidget* pWidget, 
									MATAnimatedUI::ANIMATE_STYLE Style, 
									float Delay,
									MATAnimatedFinishCallBack* pCallBack
									)
{
	

	MATAnimatedUI* pAnimatedUI = NULL;
	if(!pWidget)
		return pAnimatedUI;


	for(int i = 0; i < (int)m_AnimatedList.size(); i++)
	{
		if( m_AnimatedList[i]->m_pWidget == pWidget && m_AnimatedList[i]->m_AnimateStyle == Style)
		{
			pAnimatedUI = m_AnimatedList[i];
			i = (int)m_AnimatedList.size();
			break;
		}
	}

	if(!pAnimatedUI)
	{

		switch(Style)
		{
			
		case MATAnimatedUI::ANIMATE_STYLE_NONE:
			break;

		case MATAnimatedUI::ANIMATE_STYLE_POPPINGUP:
			pAnimatedUI = new MATAnimatedUIPoppingup();
			break;

		case MATAnimatedUI::ANIMATE_STYLE_STAMP:
			pAnimatedUI = new MATAnimatedUIStamp();
			break;

		case MATAnimatedUI::ANIMATE_STYLE_CENTERSCREEN:
			pAnimatedUI = new MATAnimatedUIMove(math::Vec2(0.5f,0.5f));
			break;

		case MATAnimatedUI::ANIMATE_STYLE_HIDE_TORIGHT:
			pAnimatedUI = new MATAnimatedUIMove(math::Vec2(1.5f,0.5f));
			break;

		case MATAnimatedUI::ANIMATE_STYLE_HIDE_TOTOP:
			pAnimatedUI = new MATAnimatedUIMove(math::Vec2(0.5f,-1.5f));
			break;

		case MATAnimatedUI::ANIMATE_STYLE_C:
			break;
		default:
			break;

		}
		m_AnimatedList.push_back(pAnimatedUI);
	}

	if(pAnimatedUI)
	{
		pAnimatedUI->m_pWidget = pWidget;
		pAnimatedUI->m_AnimateStyle = Style;
		pAnimatedUI->m_Delay = Delay;
		pAnimatedUI->m_IsFinish = false;
		pAnimatedUI->m_pCallBack = pCallBack;
	}

	return pAnimatedUI;

}



void			MATAnimatedUI::Tick(float dt)
{
	m_Delay -= dt;
	if(m_Delay <= 0)
		m_Delay = 0;	
}

void			MATAnimatedUIPoppingup::Tick(float dt)
{
	MATAnimatedUI::Tick(dt);	

	if(m_Delay > 0)
		return;

	if(m_IsFinish)
		return;

	switch(m_State)
	{
		case STATE_NONE:
			m_State = STATE_BIGGER;		
			m_Scale = 0.8f;
		break;
		case STATE_BIGGER:
			m_Scale += ( dt * 2.5f);
			if(m_Scale > 1.15f)
				m_State = STATE_RESMALL;
		break;
		case STATE_RESMALL:
			m_Scale -= dt;
			if(m_Scale <= 1.0f)
			{

				m_Scale = 1.0f;
				m_State = STATE_FINISH;
				m_IsFinish = true;
			}

		break;
		
		case STATE_FINISH:
			m_State = STATE_NONE;
		break;

		default:
		break;
	}

	if(m_pWidget)
		m_pWidget->SetScale(m_Scale);
}

MATAnimatedUIMove::MATAnimatedUIMove(const math::Vec2& MoveTo) : m_Target(MoveTo)
{

}

void			MATAnimatedUIMove::Tick(float dt)
{
	MATAnimatedUI::Tick(dt);

	if(m_Delay > 0)
		return;

	if(m_IsFinish)
		return;

	const math::Vec2 TEMP = m_pWidget->GetPosition();
	math::Vec2 OLD_DIR = m_Target - TEMP;
	const float SPEED = 4.0f;
	OLD_DIR.Normalize();
	m_pWidget->SetPositionRelativeToParent( TEMP + ( OLD_DIR * dt * SPEED )); 
	const math::Vec2 NEW_DIR = m_Target -  m_pWidget->GetPosition();

	bool Reach = true;
	if(OLD_DIR.x > 0 && NEW_DIR.x > 0 )
		Reach = false;	
	else if(OLD_DIR.x < 0 && NEW_DIR.x < 0 )
		Reach = false;	
	else if(OLD_DIR.y > 0 && NEW_DIR.y > 0 )
		Reach = false;	
	else if(OLD_DIR.y < 0 && NEW_DIR.y < 0 )
		Reach = false;

	if(Reach)
	{
		m_IsFinish = true;
		m_pWidget->SetPositionRelativeToParent(m_Target);

		if(m_pCallBack)
			m_pCallBack->OnAnimatedUIFinish();
	}

}


void			MATAnimatedUIStamp::Tick(float dt)
{
	MATAnimatedUI::Tick(dt);	

	if(m_Delay > 0)
		return;

	if(m_IsFinish)
		return;

	switch(m_State)
	{
		case STATE_NONE:

			m_State = STATE_SMALLER;		
			m_Scale = 4.0f;
			m_Alpha = 0.0f;
			{
			MATSfx* pSFX = MATSFXManager::Instance().Spawn(MATSfx::SFX_RATINGSTAR_APPEAR, m_pWidget->GetPosition(), 1.0f);
			if(pSFX)
				pSFX->SetIsPostRender(true);
			}
		break;
		
		case STATE_SMALLER:
			m_Scale -= dt * 8.0f;
			m_Alpha += dt * 4.0f;
			if(m_Alpha > 1.0f)
				m_Alpha = 1.0f;
			if(m_Scale <= 1.0f)
			{

				m_Scale = 1.0f;
				m_State = STATE_FINISH;
				MATSounds::Instance().PlaySoundSFX( MATSounds::SFX_RATINGSTAR_APPEAR);
				m_IsFinish = true;				
			}

		break;
		
		case STATE_FINISH:
			m_State = STATE_NONE;
			
		break;

		default:
		break;
	}

	if(m_pWidget)
	{
		m_pWidget->SetScale(m_Scale);
		m_pWidget->SetColor(1.0f,1.0f,1.0f,m_Alpha);
		m_pWidget->SetIsVisible(true);
	}
}






